﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
[Serializable]
public class saveToolData
{
    public int id;
    public Vector2 pos;
    public int? dir;
    public int? count;
    public int? sx;
    public int? sy;
}
[Serializable]
public class saveToolData2
{
    public int id;
    public int x;
    public int y;
    public int? dir;
    public int? count;
    public int? sx;
    public int? sy;
}
[Serializable]
public class saveData//根据实际要求微调
{
    public List<saveToolData2> arrToolData = new List<saveToolData2>();
    public int setX;
    public int setY;
    public int setZ;
}
public class prefabType
{
    static public string bgCubeOne = "bgCubeOne"; //单个方块，用于bg
    static public string toolOne = "toolOne"; //候选道具
    static public string UILevelItem = "UILevelItem"; //关卡列表
    static public string removeNode = "removeNode"; //删除插件
    static public string dirNode = "dirNode"; //方向控制插件
    static public string LevelToggle = "LevelToggle"; //层级控制
    static public string attCountNode = "attCountNode"; //数量属性
    static public string FenGeXian = "FenGeXian";//分割线
}
public class ControlBox : BaseUi
{
    public Transform bgContent;
    public Transform content;
    public Transform TestUi;
    public Transform toolContent; //道具容器
    public Transform anctionContent; //操作栏
    public Transform levelToggleContent; //用于隐藏层级
    [HideInInspector]
    public List<Transform> arrLevel = new List<Transform>();
    [HideInInspector]
    public Dictionary<string, ObjectPool> pool = new Dictionary<string, ObjectPool>();
    public InputField idInput;
    [HideInInspector]
    public int setX = 0;
    [HideInInspector]
    public int setY = 0;
    [HideInInspector]
    public int setZ = 0;
    [HideInInspector]
    public int minX = 0;
    [HideInInspector]
    public int minY = 0;
    float centerY = 0;
    float centerX = 0;
    public void init()
    {
        Global.GameProxy.ControlBox = this;
        creatorMapBg();
        creatorTool();
    }
    /// <summary>
    /// 创建或从缓冲池拿预制
    /// </summary>
    /// <param name="_name"></param>
    /// <returns></returns>
    public GameObject getPrefabByName(string _name)
    {
        string name = "Prefab/" + _name;
        if (!pool.ContainsKey(name))
        {
            pool[name] = new ObjectPool();
            pool[name].basePrefab = Resources.Load<GameObject>("Prefab/" + _name);
        }
        ObjectPool poolOne = pool[name];
        GameObject obj = poolOne.GetObject();
        if (obj == null)
        {
            obj = Instantiate(poolOne.basePrefab);
        }
        return obj;
    }
    /// <summary>
    /// 创建或从缓冲池拿预制
    /// </summary>
    /// <param name="name"></param>
    /// <param name="obj"></param>
    public void pushPrefabByName(string name, GameObject obj)
    {
        name = "Prefab/" + name;
        ObjectPool poolOne = pool[name];
        poolOne.PushObject(obj);
    }
    /// <summary>
    /// 创建背景地图
    /// </summary>
    public void creatorMapBg()
    {
        Global.GameProxy.arrBgCubeOne.Clear();
        var arrBgOne = Global.GameProxy.ControlBox.bgContent.GetComponentsInChildren<baseCub>(true);
        for (int i = 0; i < arrBgOne.Length; i++)
        {
            arrBgOne[i].recycling();
        }
        float size = 100;
        for (int i = 0; i < Global.gameData.hCount; i++)
        {
            for (int j = 0; j < Global.gameData.vCount; j++)
            {
                GameObject planOne = getPrefabByName(prefabType.bgCubeOne);
                Vector2 P = new Vector2(i, j);
                P *= size;
                bgCubeOne planOneCom = planOne.GetComponent<bgCubeOne>();
                planOneCom.init(P, prefabType.bgCubeOne, new Vector2(i, j));
                Global.GameProxy.arrBgCubeOne.Add(planOneCom);
            }
        }
        content.localScale = new Vector3(Global.gameData.contentWidth / (float)(Global.gameData.hCount * size), Global.gameData.contentHeight / (float)(Global.gameData.vCount * size), 1);
        setCenterLine(size);
    }
    /// <summary>
    /// 中间的分割线
    /// </summary>
    /// <param name="size"></param>
    public void setCenterLine(float size)
    {
        Transform parent = getAndCreatorLevel(2);//放高一点
        for (int i = parent.childCount - 1; i >= 0; i--)
        {
            Destroy(parent.GetChild(i).gameObject);
        }
        GameObject FenGeXianH = getPrefabByName(prefabType.FenGeXian);
        GameObject FenGeXianV = getPrefabByName(prefabType.FenGeXian);
        bool hIsDan = Global.gameData.hCount % 2 == 0;
        bool vIsDan = Global.gameData.vCount % 2 == 0;
        centerY = Global.gameData.vCount / 2f - (vIsDan ? 0.5f : 0);
        centerX = Global.gameData.hCount / 2f - (hIsDan ? 0.5f : 0);
        Vector2 PH = new Vector2(Global.gameData.hCount / 2f - 0.5f, centerY) * size;
        Vector2 PV = new Vector2(centerX, Global.gameData.vCount / 2f - 0.5f) * size;
        FenGeXianH.GetComponent<baseCub>()._init(PH, prefabType.FenGeXian, parent);
        FenGeXianH.transform.localScale = new Vector3(Global.gameData.hCount / 10f * size, 1, 1);
        FenGeXianV.GetComponent<baseCub>()._init(PV, prefabType.FenGeXian, parent);
        FenGeXianV.transform.localScale = new Vector3(1, Global.gameData.vCount / 10f * size, 1);
        FenGeXianH.SetActive(Global.gameData.isShowFenGeXian);
        FenGeXianV.SetActive(Global.gameData.isShowFenGeXian);
    }
    /// <summary>
    /// 生成道具候选
    /// </summary>
    public void creatorTool()
    {
        int[] arrId = MyJson.config.toolDataKeyList;
        for (int i = 0; i < arrId.Length; i++)
        {
            GameObject cubeOne = getPrefabByName(prefabType.toolOne);
            toolOne toolOneCom = cubeOne.GetComponent<toolOne>();
            toolOneCom.init(arrId[i], new saveToolData(), toolContent, prefabType.toolOne, toolStatu.inBase);
        }
    }
    /// <summary>
    /// 创建本地数据的方块
    /// </summary>
    public void creatorToolInPlan()
    {
        int level = Global.GameProxy.getLevelByIndex(Global.GameProxy.oppenFileIndex);
        saveData data = Global.GameProxy.ReadLevelData(level);
        onSetSize(data.setX, data.setY, data.setZ);
        var listSaveData = changeToSaveData(data.arrToolData);
        listSaveData.ForEach(one =>
        {
            GameObject cubeOne = getPrefabByName(prefabType.toolOne);
            toolOne toolOneCom = cubeOne.GetComponent<toolOne>();
            Transform parent = getAndCreatorLevel(MyJson.config.toolData[one.id].zIndex);
            toolOneCom.init(one.id, one, parent, prefabType.toolOne, toolStatu.inPlan);
        });
    }
    /// <summary>
    /// 设置大小时
    /// </summary>
    public void onSetSize(int x, int y, int z)
    {
        setX = x;
        setY = y;
        setZ = z;
        int maxX;
        int maxY;
        List<Vector2> arrPos = new List<Vector2>();
        if (z == 0)//两面
        {
            minX = (int)Math.Round((Global.gameData.hCount - x) / 2f, MidpointRounding.AwayFromZero);
            maxX = (int)Math.Round((Global.gameData.hCount + x) / 2f - 1, MidpointRounding.AwayFromZero);
            minY = (int)Math.Round((Global.gameData.vCount - y) / 2f, MidpointRounding.AwayFromZero);
            maxY = (int)Math.Round((Global.gameData.vCount + y) / 2f - 1, MidpointRounding.AwayFromZero);
        }
        else//4面
        {
            minX = (int)Math.Round(Global.gameData.hCount / 2f - x, MidpointRounding.AwayFromZero);
            maxX = (int)Math.Round(Global.gameData.hCount / 2f + z - 1, MidpointRounding.AwayFromZero);
            minY = (int)Math.Round(Global.gameData.vCount / 2f - y, MidpointRounding.AwayFromZero);
            maxY = (int)Math.Round(Global.gameData.vCount / 2f + y - 1, MidpointRounding.AwayFromZero);
        }
        for (int i = 0; i < Global.gameData.hCount; i++)
        {
            for (int j = 0; j < Global.gameData.vCount; j++)
            {
                bool xIsOk = i >= minX && i <= maxX;
                bool yIsOk = j >= minY && j <= maxY;
                if (xIsOk && yIsOk)
                {
                    arrPos.Add(new Vector2(i, j));
                }
            }
        }
        Global.GameProxy.ControlBox.changPlanByConfig(arrPos);
    }
    /// <summary>
    /// 通过配置生成放置方块
    /// </summary>
    /// <param name="id"></param>
    /// <param name="arrPos"></param>
    public void changPlanByConfig(List<Vector2> arrPos)
    {
        Global.GameProxy.arrBgCubeOne.ForEach(one =>
        {
            one.changeColor(false);
        });
        arrPos.ForEach(one =>
        {
            bgCubeOne plan = Global.GameProxy.arrBgCubeOne.Find(planOne =>
            {
                return Vector2.Equals(one, planOne.dataPos);
            });
            plan.changeColor(true);
        });

    }
    /// <summary>
    /// 操作栏
    /// </summary>
    /// <param name="data"></param>
    /// <param name="toolOne"></param>
    public void anctionControl(toolData data, toolOne toolOne)
    {
        baseAnction[] arrAnction = anctionContent.GetComponentsInChildren<baseAnction>();
        foreach (var item in arrAnction)
        {
            item.recycling();
        }
        if (data.hasDirection)
        {
            creatorAnction(prefabType.dirNode, toolOne);
        }
        if (data.hasCount)
        {
            creatorAnction(prefabType.attCountNode, toolOne);
        }
        creatorAnction(prefabType.removeNode, toolOne);
    }
    /// <summary>
    /// 生成操作栏
    /// </summary>
    /// <param name="type"></param>
    /// <param name="toolOne"></param>
    public void creatorAnction(string type, toolOne toolOne)
    {
        GameObject anctionOne = getPrefabByName(type);
        anctionOne.GetComponent<baseAnction>().init(anctionContent, toolOne, type);
    }
    /// <summary>
    /// 获取去层级，如果没有，便创建一个
    /// </summary>
    /// <param name="level"></param>
    /// <returns></returns>
    public Transform getAndCreatorLevel(int level)
    {
        if (arrLevel.Count <= level)
        {
            for (int i = arrLevel.Count; i <= level; i++)
            {
                GameObject newLevel = new GameObject("level" + i);
                newLevel.transform.SetParent(content, false);
                newLevel.transform.localPosition = Vector2.zero;
                arrLevel.Add(newLevel.transform);
                GameObject newLevelToggle = getPrefabByName(prefabType.LevelToggle);
                LevelToggle levelCom = newLevelToggle.GetComponent<LevelToggle>();
                levelCom.init(levelToggleContent, newLevel, prefabType.LevelToggle, i);
            }
        }
        return arrLevel[level];
    }
    public override void _onClick(string btnTag, GameObject obj)
    {
        base._onClick(btnTag, obj);
        switch (btnTag)
        {
            case "save":
                var listToolData = getSaveData();
                Global.GameProxy.saveData(listToolData);
                break;
            case "back":
                Global.GameProxy.UiControl.showControl(false);
                break;
            case "previousLevel":
                enter(Mathf.Max(0, Global.GameProxy.oppenFileIndex - 1));
                break;
            case "nextLevel":
                enter(Mathf.Min(Global.GameProxy.arrFileInfo.Count - 1, Global.GameProxy.oppenFileIndex + 1));
                break;
            case "tuoZhan":
                showUi(TestUi.gameObject);
                break;
            default:
                Debug.Log("点击了" + btnTag + "未处理");
                break;
        }
    }
    /// <summary>
    /// 获取存储数据
    /// </summary>
    /// <returns></returns>
    public saveData getSaveData()
    {
        return new saveData()
        {
            arrToolData = creatorData(),
            setX = setX,
            setY = setY,
            setZ = setZ,
        };
    }
    /// <summary>
    /// 创建存储数据
    /// </summary>
    /// <returns></returns>
    public List<saveToolData2> creatorData()
    {
        List<saveToolData> listToolData = new List<saveToolData>();
        arrLevel.ForEach(one =>
        {
            for (int i = 0; i < one.childCount; i++)
            {
                if (one.GetChild(i).gameObject.activeSelf)
                {
                    toolOne com = one.GetChild(i).GetComponent<toolOne>();
                    if (com)
                    {
                        saveToolData saveData = com.saveData;
                        listToolData.Add(saveData);
                    }
                }
            }
        });
        var result = changeToSaveData2(listToolData);
        return result;
    }
    /// <summary>
    /// 将数据转为存储格式
    /// </summary>
    /// <param name="saveToolData"></param>
    /// <returns></returns>
    public List<saveToolData2> changeToSaveData2(List<saveToolData> saveToolData)
    {
        List<saveToolData2> listToolData = new List<saveToolData2>();
        saveToolData.ForEach(one =>
        {
            var newOne = new saveToolData2()
            {
                id = one.id,
                x = (int)one.pos.x,
                y = (int)one.pos.y,
                count = one.count,
                dir = one.dir,
                sx = one.sx,
                sy = one.sy,
            };
            newOne.x -= minX;
            newOne.y -= minY;
            listToolData.Add(newOne);
        });
        return listToolData;
    }
    /// <summary>
    /// 将数据转为游戏格式
    /// </summary>
    /// <returns></returns>
    public List<saveToolData> changeToSaveData(List<saveToolData2> saveToolData2)
    {
        List<saveToolData> listToolData = new List<saveToolData>();
        saveToolData2.ForEach(one =>
        {
            var newOne = new saveToolData()
            {
                id = one.id,
                pos = new Vector2(one.x, one.y),
                count = one.count,
                dir = one.dir,
                sx = one.sx,
                sy = one.sy,
            };
            newOne.pos.x += minX;
            newOne.pos.y += minY;
            listToolData.Add(newOne);
        });
        return listToolData;
    }
    /// <summary>
    /// 插入关卡
    /// </summary>
    /// <param name="index"></param>
    public void enter(int index)
    {
        toolOne[] arrToolOne = content.GetComponentsInChildren<toolOne>(true);
        foreach (var item in arrToolOne)
        {
            item.recycling();
        }
        Global.GameProxy.arrBgCubeOne.ForEach(one =>
        {
            one.arrHasLevel = new Dictionary<int, toolOne>();
        });
        Global.GameProxy.oppenFileIndex = index;
        idInput.text = Global.GameProxy.GetLevelByFileName(Global.GameProxy.getNameByIndex(index)).ToString();
        creatorToolInPlan();
        Global.GameProxy.UiControl.showControl(true);
    }
    /// <summary>
    /// 切出游戏
    /// </summary>
    /// <param name="isPaused"></param>
    void OnApplicationPause(bool isPaused)
    {
        if (isPaused)
        {
            Global.LocalData.SaveData();
        }
    }
    /// <summary>
    /// 退出游戏
    /// </summary>
    void OnApplicationQuit()
    {
        Global.LocalData.SaveData();
    }
}